package org.fixed.dubboconsumer.core.util;

import com.fasterxml.jackson.databind.JavaType;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springside.modules.utils.collection.CollectionUtil;
import org.springside.modules.utils.mapper.JsonMapper;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * @author [xuzhongwei]
 * @see [相关类/方法]
 * @since 2019/8/22
 */
public class ReflectionUtils {


    /**
     * 封装对应的参数
     *
     * @param parameterType 参数TYpe
     * @param param         参数
     * @return
     */
    public static Object constactParamete(Type parameterType, String param) {
        Object o = null;
        if (parameterType instanceof ParameterizedTypeImpl) {
            ParameterizedType c = (ParameterizedType) parameterType;
            Class rawType = (Class) c.getRawType();
            if (isCollection(rawType)) {
                if (ArrayUtils.isNotEmpty(c.getActualTypeArguments())) {
                    //构造集合 list 有泛型限定
                    JavaType javaType = JsonMapper.nonEmptyMapper().buildCollectionType(rawType, (Class<?>) c.getActualTypeArguments()[0]);
                    o = JsonMapper.nonEmptyMapper().fromJson(param, javaType);
                    if (o == null) {
                        throw new RuntimeException("参数异常");
                    }
                } else {
                    //list 无泛型限定
                    o = JsonMapper.nonEmptyMapper().fromJson(param, rawType);
                }
            } else {
                //非集合类型的其他泛型限定
                o = JsonMapper.nonEmptyMapper().fromJson(param, rawType);
            }
        } else {
            if (parameterType.getTypeName().equals("java.util.Date")) {
                if(StringUtils.isNumeric(param)){
                    o = JsonMapper.nonEmptyMapper().fromJson(param, (Class) parameterType);
                }else {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                    ParsePosition parsePosition = new ParsePosition(0);

                    o = dateFormat.parse(param,parsePosition);

                }
            } else if (isConstructor((Class) parameterType)) {
                //bean
                o = JsonMapper.nonEmptyMapper().fromJson(param, (Class) parameterType);
            } else {
                //String ，基本数据类型机器包装类型
                o = param;
            }
        }
        return o;
    }

    /**
     * 判断是否集合List、Set、ArrayList
     *
     * @param rawType
     * @return
     */
    private static boolean isCollection(Class rawType) {
        if (rawType.isInterface()) {
            //接口判断父类是否有Collection
            Class<?>[] suCl = rawType.getInterfaces();
            if (ArrayUtils.isNotEmpty(suCl)) {
                for (Class<?> ci : suCl) {
                    if (ci.getTypeName().equals("java.util.Collection")) {
                        return true;
                    } else {
                        boolean isCollection = isCollection(ci);
                        if (isCollection) {
                            return true;
                        }
                    }
                }
            }
        } else {
            Class<?>[] interfaceArr = rawType.getInterfaces();
            if (ArrayUtils.isNotEmpty(interfaceArr)) {
                for (Class<?> ci : interfaceArr) {
                    boolean isCollection = isCollection(ci);
                    if (isCollection) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 判断是否基本数据类型
     *
     * @param clz
     * @return
     */
    private static boolean isWrapClass(Class clz) {
        try {
            return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 是否复杂对象
     *
     * @param clz
     * @return
     */
    private static boolean isConstructor(Class clz) {
        //基础类型
        if (clz.isPrimitive()) {
            return false;
        }
        //基础类型的包装类型
        if (isWrapClass(clz)) {
            return false;
        }
        if (clz.getTypeName().equals("java.lang.String")) {
            return false;
        }
        return true;
    }

    public static Method getMethod(Class clszz, String methodName, List<String> paramType) throws NoSuchMethodException, ClassNotFoundException {
        if (CollectionUtil.isNotEmpty(paramType)) {
            Class[] parameterTypes = new Class[paramType.size()];
            for (int i = 0; i < paramType.size(); i++) {
                parameterTypes[i] = Class.forName(paramType.get(i));
            }
            return clszz.getMethod(methodName, parameterTypes);
        } else {
            return clszz.getMethod(methodName);
        }
    }
}
